﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CloudReader.Net.Protocol
{
    public class Parser
    {
        static void SetEOF(ref byte[] data)
        {
            data[data.Length - 3] = 69;
            data[data.Length - 2] = 79;
            data[data.Length - 1] = 70;
        }
        internal static bool isEOF(byte[] data)
        {
            return data[data.Length - 3] == 69 && data[data.Length - 2] == 79 && data[data.Length - 1] == 70;
        }
        public static byte[] Encode(CloudReaderPackage p)
        {
            var data = new byte[p.TotalLength + 8];
            SetEOF(ref data);
            Array.Copy(BitConverter.GetBytes(p.TotalLength), data, 4);
            data[4] = (byte)p.Type;
            var q = Encoding.UTF8.GetBytes(p.Data);
            var d = Encrypt(ref q);
            Array.Copy(d, 0, data, 5, data.Length - 8);
            return data;
        }
        public static CloudReaderPackage Decode(byte[] data)
        {
            var l = BitConverter.ToInt32(data, 0);
            var p = new CloudReaderPackage()
            {
                TotalLength = l,
                Type = (CloudReaderProtocolType)data[4]
            };
            if (l > data.Length)
            {
                goto ex;
            }
            switch (p.Type)
            {
                case CloudReaderProtocolType.Broadcast:
                    if (l > CloudReaderPackage.BroadCastMaxSize)
                        goto ex;
                    break;
                case CloudReaderProtocolType.Image:
                    if (l > CloudReaderPackage.ImageMaxSize)
                        goto ex;
                    break;
                case CloudReaderProtocolType.Message:
                    if (l > CloudReaderPackage.MessageMaxSize)
                        goto ex;
                    break;
                case CloudReaderProtocolType.Response:
                    if (l > 1)
                        goto ex;
                    break;
                case CloudReaderProtocolType.String:
                    if (l > CloudReaderPackage.StringMaxSize)
                        goto ex;
                    break;
                case CloudReaderProtocolType.Validate:
                    if (l > CloudReaderPackage.ValidateMaxSize)
                        goto ex;
                    break;
            }
            var d = new byte[l];
            Array.Copy(data, 5, d, 0, d.Length);
            p.Data = Encoding.UTF8.GetString(Decrypt(ref d));
            return p;
            ex:
            throw new ArgumentException("标头损坏");
        }
        static byte[] Decrypt(ref byte[] data) { return data; }
        static byte[] Encrypt(ref byte[] data) { return data; }
        public CloudReaderPackage this[string content, bool isLogin]
        {
            get
            {
                if (!isLogin)
                {
                    return new CloudReaderPackage()
                    {
                        Type = CloudReaderProtocolType.String,
                        Data = content,
                        TotalLength = Encoding.UTF8.GetByteCount(content)
                    };
                }
                else
                {
                    return new CloudReaderPackage()
                    {
                        Type = CloudReaderProtocolType.Validate,
                        Data = content,
                        TotalLength = Encoding.UTF8.GetByteCount(content)
                    };
                }
            }
        }
        public CloudReaderPackage this[bool result]
        {
            get
            {
                var p = new CloudReaderPackage()
                {
                    Type = CloudReaderProtocolType.Response,
                    TotalLength = 1
                };
                if (result)
                {
                    p.Data = "1";
                }
                else
                {
                    p.Data = "0";
                }
                return p;
            }
        }
        public CloudReaderPackage this[CloudReaderOperationResult result]
        {
            get
            {
                return new CloudReaderPackage()
                {
                    Type = CloudReaderProtocolType.Response,
                    TotalLength = 1,
                    Data = Convert.ToString(result)
                };

            }
        }
        public CloudReaderPackage this[CloudReaderProtocolType t]
        {
            get
            {
                if (t == CloudReaderProtocolType.HeartBeat)
                {
                    return new CloudReaderPackage()
                    {
                        Type = CloudReaderProtocolType.HeartBeat,
                        TotalLength = 1,
                        Data = "1"
                    };
                }
                return null;
            }
        }
    }
}
